﻿/**
 *		网络通信模块
 *@notes	特别说明：一个控制器只能属于一个线程，其他线程只能调用add方法，
 *				进入到控制器所在线程后，与socket相关的资源都由其控制，包括释放资源。
 *@date		2019年11月27日
 *  *		socket控制器设计
 * 1. 需求
 *		多个socket可以放在一个线程中，由socket进行调度，发现有需要读写的socket，调用其对应的回调函数。
 *		在回调函数中可以增加新的socket到列表中，也可以执行删除操作，并且需要保证线程安全。
 * 2. 设计方案
 *		定义socket项，包含socket、回调、状态。定义控制器对象，包含正在使用中链表，新增删除链表。在线程中遍历使用中
 * 链表，发现有socket需要读写数据，找到对应socket并调用。
 *		外部线程或者内部线程的增加删除操作，只能操作新增删除链表。删除时先将要删除的socket放入链表，然后判断当前操作的
 * socket是否是正在回调中，如果是在回调中，则等待回调完成。
 *		删除操作可能是回调中删除自己，这样调用会上锁，删除会上锁，就会导致死锁。为防止这一现象发生，要求上层在回调中
 * 不可以调用删除自己的操作。如果需要删除，则在回调的返回中执行 return SOCKET_DISCONNECT，这样回调结束后，在内部就会
 * 知道需要将当前socket删除。
 *		socket的回调函数只有三种值可以返回：SOCKET_OK：正常返回；SOCKET_DISCONNECT：回调结束后删除本socket，并对socket执行
 * OssCloseSocket操作；SOCKET_REMOVE：回调结束后删除本socket，但不执行OssCloseSocket操作。
 * 特别说明：回调中是不能执行删除自己的动作，即不可以调用OssDeleteSocketItem删除自己，但可以调用OssDeleteSocketItem
 *删除其他socket;
 */

#ifndef OSS_SOCKET_CTRL_H_
#define OSS_SOCKET_CTRL_H_
#include "ossType.h"
#include "ossSocket.h"

//socket状态
#define SOCKET_OK               0x00        //SOCKET良好
#define SOCKET_DISCONNECT       0x01        //当前socket断开连接
#define SOCKET_READ             0x02		//读状态
#define SOCKET_REMOVE			0x03		//移除，但不关闭socket

OSS_EXTERN_BEG

/**
 *       socket接收数据的回调函数
 *@socket       接收数据的socket
 *@state        当前socket的状态,参考“socket状态”
 *@pContent     回调函数的上下文
 *@return       返回当前的socket状态，如果返回SOCKET_DISCONNECT，则需要将其删除
 *					SOCKET_OK：正常返回；
 *					SOCKET_DISCONNECT：回调结束后删除本socket，并对socket执行
 *							OssCloseSocket操作；
 *					SOCKET_REMOVE：回调结束后删除本socket，但不执行OssCloseSocket操作。
 * 特别说明：回调中是不能执行删除自己的动作，即不可以调用OssDeleteSocketItem删除自己，但可以调用OssDeleteSocketItem
 *删除其他socket;
 */
typedef int (*SocketCallback)(Socket socket,int state,void* pContent);

/**
 *		oss_create_socket_ctrl 创建socket控制器
 *@return		返回控制器句柄（对外封装，不告知具体结构体）
 *				失败返回NULL
 *@notes		socket控制的所有操作都基于该句柄
 *@author		吴建凰 2015年11月30日
 */
Handle OssCreateSocketCtrl();

/**
 *		oss_free_socket_ctrl 释放socket控制器
 *@hsocketCtrl		socket控制器句柄
 *@return			无
 *@author			吴建凰 2015年11月30日
 */
void OssFreeSocketCtrl(Handle hsocketCtrl);

/**
 *      OssAddSocketItem 添加一个socket项
 *@hsocketCtrl		socket控制器句柄
 *@socket			需要控制的socket
 *@callback			socket对应的回调函数，当socket有数据、被关闭或者异常的情况会调用该回调函数
 *@lpcontext		回调函数上下文
 *@return			成功返回 TRUE
 *					失败返回 FALSE
 *@notes			一个socket只能与一个回调函数对应，多次放入则只使用最后一次的回调函数
 *@author			吴建凰 2015年11月30日
 */
Bool OssAddSocketItem(Handle hsocketCtrl,Socket socket
						,SocketCallback callback,void* lpcontext);

/**
 *      OssDeleteSocketItem 删除一个socket项
 *@hsocketCtrl		socket控制器句柄
 *@socket			需要删除的socket
 *@return			成功删除返回			TRUE
 *					指定的socket不存在返回	FALSE
 *@notes			如果成功删除，对应的socket也被删除（ 执行oss_close_socket(socket)）
 *@author			吴建凰 2015年11月30日
 */
Bool OssDeleteSocketItem(Handle hsocketCtrl,Socket socket);

/**
 *		OssRemoveSocketItem 移除一个socket项
 *@hsocketCtrl		socket控制器句柄
 *@socket			需要删除的socket
 *@return			成功移除返回			TRUE
 *					指定的socket不存在返回	FALSE
 *@notes			移除不会关闭socket
 *@author			吴建凰 2015年11月30日
 */
Bool OssRemoveSocketItem(Handle hsocketCtrl,Socket socket);

/**
 *      oss_delete_all_socket_item 删除所有的socket项
 *@hsocketCtrl		socket控制器句柄
 *@return			无
 *@notes			所有socket都会执行oss_close_socket(socket)
 *@author			吴建凰 2015年11月30日
 */
void OssDeleteAllSocketItem(Handle hsocketCtrl);

/**
 *		oss_socket_ctrl_single_step 单步调用一次
 *@hsocketCtrl		socket控制器句柄
 *@timeout			执行的超时时间，即判断在timeout时间内有没有socket来数据，有则调用其回调函数
 *@return			有socket来数据返回  TRUE
 *					无则返回			FALSE
 *@author			吴建凰 2015年11月30日
 */
Bool OssSocketCtrlSingleStep(Handle hsocketCtrl,DWord timeout);

/**
 *		oss_socket_ctrl_get_count 获取socket个数
 *@hsocketCtrl		socket控制器句柄
 *@return			返回socket控制列表中包含的socket个数
 *@author			吴建凰 2015年11月30日
 */
int OssSocketCtrlGetCount(Handle hsocketCtrl);

/**
 *		OssSocketCtrlIsExist 判断指定的socket在不在控制队列中
 *@
 */
Bool OssSocketCtrlIsExist(Handle hsocketCtrl,Socket s_fd);


OSS_EXTERN_END
#endif
